
local CameraControl = class("CameraControl", require("unity.LuaMonoBehaviour"))

---
--- mDampTime mScreenEdgeBuffer mMinSize mCamera
---
function CameraControl:Awake()
    self.mTargets = self.mTargets or {}      -- [Transfrom]
    self.mZoomSpeed = 0
    self.mMoveVelocity = Vector3.New()
    self.mDesiredPosition = Vector3.New()
end

function CameraControl:FixedUpdate()
    self:Move()
    self:Zoom()
end

function CameraControl:SetTargets(targets)
    self.mTargets = targets
end

function CameraControl:Move()
    self:FindAveragePosition()
    self.transform.position,self.mMoveVelocity = Vector3.SmoothDamp(self.transform.position, self.mDesiredPosition, self.mMoveVelocity, self.mDampTime)
end

function CameraControl:FindAveragePosition()
    local averagePos = Vector3.New()
    local numTargets = 0
    for i,v in ipairs(self.mTargets) do
        if v.gameObject.activeSelf then
            averagePos:Add(v.position)
            numTargets = numTargets + 1
        end
    end
    if numTargets > 0 then
        averagePos:Div(numTargets)
    end
    averagePos.y = self.transform.position.y
    self.mDesiredPosition = averagePos
end

function CameraControl:Zoom()
    local requiredSize = self:FindRequiredSize()
    self.mCamera.orthographicSize,self.mZoomSpeed = Mathf.SmoothDamp(self.mCamera.orthographicSize, requiredSize, self.mZoomSpeed, self.mDampTime)
end

function CameraControl:FindRequiredSize()
    local desiredLocalPos = self.transform:InverseTransformPoint(self.mDesiredPosition)
    local size = 0
    for i,v in ipairs(self.mTargets) do
        if v.gameObject.activeSelf then
            local targetLocalPos = self.transform:InverseTransformPoint(v.position)
            local desiredPosToTarget = targetLocalPos - desiredLocalPos
            size = Mathf.Max(size, Mathf.Abs(desiredPosToTarget.y))
            size = Mathf.Max(size, Mathf.Abs(desiredPosToTarget.x) / self.mCamera.aspect);
        end
    end
    size = size + self.mScreenEdgeBuffer
    size = Mathf.Max (size, self.mMinSize);
    return size
end

function CameraControl:SetStartPositionAndSize()
    self:FindAveragePosition ()
    self.transform.position = self.mDesiredPosition
    self.mCamera.orthographicSize = self:FindRequiredSize ()
end

return CameraControl
